package Controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"math"
	"strconv"
	"time"
	"web_back_go/Common"
	"web_back_go/DAO/gorm"
	"web_back_go/DAO/gorm/GormModel"
	"web_back_go/Dto"
	"web_back_go/Response"
)

type UserCollectionDto struct {
	// 收藏id
	Id int64 `json:"id"`
	// 商品名称
	ProdName string `json:"prodName"`
	// 收藏时间
	CreateTime time.Time `json:"createTime"`
}

/*
IsCollection
@Description: 判断商品是否被收藏
@prodId 商品id
*/
func IsCollection(c *gin.Context) {
	prodIdStr := c.Query("prodId")
	prodId, err := strconv.ParseInt(prodIdStr, 10, 64)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Msg:     "参数错误",
			Data:    nil,
			Sign:    nil,
			Success: true,
			Fail:    false,
		})
		return
	}
	log.Println(fmt.Sprintf("prodId=%d", prodId))

	db := gorm.Db
	//先判断商品存不存在
	var prodCount int64
	db.Table("tz_prod").Where("prod_id = ?", prodId).Count(&prodCount)
	if prodCount == 0 {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Msg:     "该商品不存在",
			Data:    nil,
			Sign:    nil,
			Success: true,
			Fail:    false,
		})
		return
	}

	//从Token获取用户ID
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userId, _, err := Common.CodeToken(token)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	//判断商品是否被收藏 返回的
	/*
		userCollectionService.count(new LambdaQueryWrapper<UserCollection>()
		                .eq(UserCollection::getProdId, prodId)
		                .eq(UserCollection::getUserId, SecurityUtils.getUser().getUserId())) > 0
	*/
	var userCollectionCount int64
	db.Where("prod_id = ? AND user_id = ?", prodId, userId).Count(&userCollectionCount)
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    userCollectionCount > 0,
		Success: true,
		Msg:     "Success",
	})
}

/*
GetUserCollectionCount
@Description: 获取用户收藏数量
@return      int64
*/
func GetUserCollectionCount(c *gin.Context) {
	//从Token获取用户ID
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userId, _, err := Common.CodeToken(token)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00005",
			Data:    "服务器出了点小差",
			Success: true,
			Msg:     nil,
		})
		return
	}
	db := gorm.Db
	var count int64
	db.Model(&GormModel.TzUserCollection{}).Where("user_id = ?", userId).Count(&count)

	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Data:      count,
		Success:   true,
		Msg:       nil,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
	})
}

type AddOrCancelRequest struct {
	ProdId int64 `json:"prodId"`
}

/*
AddOrCancelCollection
@Description: 添加或取消收藏
@return
*/
func AddOrCancelCollection(c *gin.Context) {
	var request AddOrCancelRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		log.Println(err)
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Msg:     "请求体格式错误",
			Data:    nil,
			Sign:    nil,
			Success: false,
			Fail:    true,
		})
		return
	}
	prodId := request.ProdId
	//log.Println(prodId)

	tx := gorm.Db.Begin()

	//回退函数
	defer func() {
		if err := recover(); err != nil {
			tx.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		}
	}()

	//先判断商品存不存在
	var prodCount int64
	tx.Model(&GormModel.TzProd{}).Where("prod_id = ?", prodId).Count(&prodCount)
	if prodCount == 0 {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Msg:     "该商品不存在",
			Data:    nil,
			Sign:    nil,
			Success: true,
			Fail:    false,
		})
		return
	}

	//从Token获取用户ID
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userId, _, err := Common.CodeToken(token)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00005",
			Data:    nil,
			Success: true,
			Msg:     "服务器出了点小差",
		})
		return
	}
	//判断商品是否被收藏
	if tx.Where("prod_id =? AND user_id =?", prodId, userId).First(&GormModel.TzUserCollection{}).RowsAffected > 0 {
		//取消收藏
		tx.Where("prod_id =? AND user_id =?", prodId, userId).Delete(&GormModel.TzUserCollection{})
		tx.Commit()
		c.JSON(200, Response.ResponseBody{
			Code:    "00000",
			Data:    "ok",
			Success: true,
			Msg:     nil,
			Version: "1.0",
		})
		return
	} else {

		log.Println(Common.GetCurrentTime())
		tx.Create(&GormModel.TzUserCollection{
			ProdID:     prodId,
			UserID:     userId,
			CreateTime: Common.GetCurrentTime(),
		})
		tx.Commit()
		c.JSON(200, Response.ResponseBody{
			Code:    "00000",
			Data:    "ok",
			Success: true,
			Msg:     nil,
			Version: "1.0",
		})
	}
}

/*
GetCollectionProdsPage
@Description: 获取用户收藏的商品列表
@currentStr 当前页码
@sizeStr 每页大小
@return
*/
func GetCollectionProdsPage(c *gin.Context) {
	currentStr := c.Query("current")
	sizeStr := c.Query("size")
	page, err := strconv.Atoi(currentStr)

	var count int64
	if err != nil || page < 1 {
		page = 1
	}

	size, err := strconv.Atoi(sizeStr)
	if err != nil || size < 1 {
		size = 10
	}

	db := gorm.Db
	//从Token获取用户ID
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userId, _, err := Common.CodeToken(token)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00005",
			Data:    nil,
			Success: true,
			Msg:     "服务器出了点小差",
		})
		return
	}

	// 计算总数
	db.Model(&GormModel.TzUserCollection{}).Where("user_id = ?", userId).Count(&count)
	offset := (page - 1) * size
	type CollectionProd struct {
		ProdId   int64   `json:"prodId"`
		Pic      string  `json:"pic"`
		ProdName string  `json:"prodName"`
		Price    float64 `json:"price"`
		Brief    string  `json:"brief"`
		ShopName string  `json:"shopName"`
	}

	var collectionList []CollectionProd
	db.Raw(`
	SELECT
		p.prod_id,
		p.pic,
		p.prod_name,
		p.price,
		p.brief,
		sd.shop_name
	FROM tz_prod p
	LEFT JOIN tz_shop_detail sd ON p.shop_id = sd.shop_id
	WHERE p.prod_id IN (
		SELECT uc.prod_id FROM tz_user_collection uc WHERE uc.user_id = ?
	)
	LIMIT ? OFFSET ?
`, userId, size, offset).Scan(&collectionList)

	// 将 collectionList 转换为 ProductDto 列表（如果需要）
	var productDtos []Dto.ProductDto
	for _, item := range collectionList {
		productDtos = append(productDtos, Dto.ProductDto{
			ProdId: item.ProdId,
			//Pic:      "https://img.mall4j.com/" + item.Pic,
			Pic:      item.Pic,
			ProdName: item.ProdName,
			Price:    item.Price,
			Brief:    item.Brief,
			ShopName: item.ShopName,
		})
	}
	c.JSON(200, Response.ResponseBody{
		Code: "00000",
		Data: Common.PageParam1[Dto.ProductDto]{
			Current: page,
			Total:   count,
			Size:    size,
			Records: productDtos,
			Pages:   int(math.Ceil(float64(count) / float64(size))),
		},
		Success: true,
		Msg:     nil,
		Version: "1.0",
	})
}

/*
GetUserCollectionDtoPageByUserId
@Description: 获取用户收藏的商品列表
@currentStr 当前页码
@sizeStr 每页大小
*/
func GetUserCollectionDtoPageByUserId(c *gin.Context) {
	currentStr := c.Query("current")
	sizeStr := c.Query("size")
	page, err := strconv.Atoi(currentStr)

	var count int64
	if err != nil || page < 1 {
		page = 1
	}

	size, err := strconv.Atoi(sizeStr)
	if err != nil || size < 1 {
		size = 10
	}

	db := gorm.Db
	//从Token获取用户ID
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userId, _, err := Common.CodeToken(token)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00005",
			Data:    nil,
			Success: true,
			Msg:     "服务器出了点小差",
		})
		return
	}
	/*
	   select
	   uc.id,
	   uc.create_time,
	   p.prod_name
	   from
	   tz_user_collection  uc
	   left join tz_prod p on uc.prod_id=p.prod_id
	*/
	var collectionList []UserCollectionDto
	db.Raw(`
	SELECT
		uc.id,
		uc.create_time,
		p.prod_name
	FROM
		tz_user_collection uc
	LEFT JOIN tz_prod p ON uc.prod_id = p.prod_id
	WHERE
		uc.user_id = ?
	ORDER BY
		uc.create_time DESC
	LIMIT ? OFFSET ?
`, userId, size, (page-1)*size).Scan(&collectionList)
	// 计算总数
	db.Table("tz_user_collection uc").
		Joins("LEFT JOIN tz_prod p ON uc.prod_id = p.prod_id").
		Where("uc.user_id = ? AND p.prod_id IS NOT NULL", userId).
		Count(&count)

	c.JSON(200, Response.ResponseBody{
		Code: "00000",
		Data: Common.PageParam1[UserCollectionDto]{
			Current: page,
			Total:   count,
			Size:    size,
			Records: collectionList,
			Pages:   int(math.Ceil(float64(count) / float64(size))),
		},
		Success:   true,
		Msg:       nil,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
	})

}
